/*
 * Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
 *
 * Licensed under the Mulan PSL v2.
 * You can use this file according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of the License at
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
 * FOR MORE DETAILS.
 */

#pragma once

#include <map>

#include "Utility/Configuration/SGParameter.h"

#include "DataStructure/Common/Out.h"
#include "DataStructure/Input/Solver/Subcase.h"

#include "Import/BDFImport/BDFImport.h"
#include "Import/BDFImport/BDFParserBase.h"
#include "Import/ImportAPI/Common/ImportNamespace.h"
DBSERVICEFACTORY_DEC

/**
 * @brief 注册解析Control块的Nastran函数。
 *
 * @param ENTRYNAME 词条名称，ex:SOL。
 */

#define CONTROLDATA_ENTRY_PARSER_REG(ENTRYNAME)                                                             \
    namespace                                                                                               \
    {                                                                                                       \
        bool register_##ENTRYNAME = SG::Import::BDF::CaseDataEntryParserFactory::GetInstance ()->Register ( \
            #ENTRYNAME, &SG::Import::BDF::CONTROLDATA::Parse##ENTRYNAME);                                   \
    }

/**
 * @brief 解析Control块中关于subcase内容。
 *
 * @param controlInfo 输入的结构体
 * @param subcase 【out】 根据controlInfo内容向subcase内填充
 * @return 如果成功，返回 true；否则返回 false。
 */

#define CONTROLDATA_ENTRY_PARSER_DECL(ENTRYNAME)                                                                                   \
    namespace SG                                                                                                                   \
    {                                                                                                                              \
        namespace Import                                                                                                           \
        {                                                                                                                          \
            namespace BDF                                                                                                          \
            {                                                                                                                      \
                namespace CONTROLDATA                                                                                              \
                {                                                                                                                  \
                    SG::DataStructure::Common::Status Parse##ENTRYNAME (SG::DataStructure::FEM::Subcase::ControlInfo& controlInfo, \
                                                                        SG::Utility::SGParameter& _OUT                subcase);                   \
                }                                                                                                                  \
            }                                                                                                                      \
        }                                                                                                                          \
    }

#define CONTROLDATA_ENTRY_PARSER_IMPL(ENTRYNAME)                                                                        \
    SG::DataStructure::Common::Status SG::Import::BDF::CONTROLDATA::Parse##ENTRYNAME (                                  \
        SG::DataStructure::FEM::Subcase::ControlInfo& controlInfo, SG::Utility::SGParameter& _OUT subcase)              \
    {                                                                                                                   \
        SG::Utility::SGParameter Parameter##ENTRYNAME;                                                                  \
        Parameter##ENTRYNAME.AddString (SG::DataStructure::FEM::Subcase::SC_MAINKEY, controlInfo.m_Vaule);              \
        if (controlInfo.m_vecKeys.size () != 0)                                                                         \
        {                                                                                                               \
            Parameter##ENTRYNAME.AddStringArray (SG::DataStructure::FEM::Subcase::SC_VECTORKEY, controlInfo.m_vecKeys); \
        }                                                                                                               \
        if (controlInfo.m_mapKeys.size () != 0)                                                                         \
        {                                                                                                               \
            SG::Utility::SGParameter mapParameter;                                                                      \
            for (auto iter : controlInfo.m_mapKeys)                                                                     \
            {                                                                                                           \
                mapParameter.AddString (iter.first, iter.second);                                                       \
            }                                                                                                           \
            Parameter##ENTRYNAME.AddValue (SG::DataStructure::FEM::Subcase::SC_MAPKEY, mapParameter);                   \
        }                                                                                                               \
        subcase.AddValue (#ENTRYNAME, Parameter##ENTRYNAME);                                                            \
        return SG::DataStructure::Common::Status::STATUS_Success;                                                       \
    }

SG_IMPORT_BDF_NAMESPACE_OPEN

/// @brief 词条解析工厂类
class CaseDataEntryParserFactory
{
  public:
    using NEParseFunP = SG::DataStructure::Common::Status (*) (SG::DataStructure::FEM::Subcase::ControlInfo&, SG::Utility::SGParameter&);

    using NEParseMap = std::map<std::string, NEParseFunP>;

    /// @brief 注册解析函数
    /// @param EntryType 词条名称 关键词
    /// @param ParseFunP 解析函数
    /// @return
    bool Register (const std::string& EntryType, NEParseFunP NastranParseSP);

    /// @brief 反注册某解析函数
    /// @param EntryType
    void Unregister (const std::string& EntryType);

    /// @brief 清空所有注册的解析函数
    void UnregisterAll ();

    /// @brief 清空m_FirstSubcaseID等成员变量
    void ClearField ();

    /// @brief 获取解析函数
    /// @param EntryType
    /// @return
    NEParseFunP GetFunction (const std::string& EntryType);

    /// @brief 单例模式获取实例
    /// @return
    static CaseDataEntryParserFactory* GetInstance ();

  public:
    size_t m_SolutionSequences = 0;  // 记录sol
    size_t m_FirstSubcaseID    = 0;  // 记录第一个工况ID
  private:
    NEParseMap m_NEParseFunMap;      /// 词条解析函数映射

    CaseDataEntryParserFactory ();
};

SG_IMPORT_BDF_NAMESPACE_CLOSE
